<?php
	class Controller extends GlobalController
	{
		/**
		 * Defines whether to check access (default: true)
		 *
		 * @var boolean
		 */
		public $checkAccess = true;

		/**
		 * Defines whether to check authentication (default: true)
		 *
		 * @var boolean
		 */
		public $checkAuthentication = true;
		
		/**
		 * defines whether the controller is to be cached
		 *
		 * @var boolean
		 */
		public $isCached = true;
		
		/**
		 * defines whether the logging is enabled on the page
		 *
		 * @var boolean
		 */
		public $use_logging = true;
		
		/**
		 * Public pages (no authorization required)
		 * @var array
		 */
		public $publicPages = array();

		/**
		 * Developer pages (developer authorization required)
		 * @var array
		 */
		public $devPages = array();

		/**
		 * Private pages (customer authorization required)
		 * @var array
		 */
		public $privatePages = array();
		
		/**
		 * Defines whether the page has left column
		 *
		 * @var boolean
		 */
		public $hasLeftColumn = true;
		
		
	    /**
		 * Is loaded before any controller and performs common for all controllers actions
		 *
		 * @param array $url page url, devided into controller, action and parameters 
		 */			
		function BeforeLoad($url)
		{
			global $object;

			//DevUI
			require_once(COMPONENTS.SEPARATOR.'DevUI/devui.php');
			DevUI::Initilize();
			
			require_once(COMPONENTS.SEPARATOR.'jquery.php');
			
			if (isset($this->request->session[usertheme]))
			{
				if (file_exists(THEMES.SEPARATOR.$this->request->session[usertheme]))
				{
					$this->theme = $this->request->session[usertheme];
				}
				else 
				{
					echo "<div class = 'error'>".LANG_THEME_NOT_EXISTS."</div>";
				}
			}
						
			$this->CheckAuthentication($url['action']);
			
			//add menu
			$this->IncludeElement('menus');
			
			//add arrays
			$this->IncludeElement('arrays');
			
			//if it is not 'main' controller
			if (($this->name != 'main') && ($this->name != 'pageNotExists') && ($object->config->use_table_access))
			{
				//get table_id for permission operations
				$table = $this->GetModelObject('systemAccess')->Execute(array('table_name'=>$this->controller_model->table_name), 'sp_system_tables_get_by_name');
				$this->data[general][table_id] = $table[system_table_id];
			}
			
			//validation errors
			$this->data[validation_errors] = $this->controller_model->validation_errors;
			
			//for pagination
			$this->max_records = 1000;
			if (empty($_SESSION[userresultsperpage])) $_SESSION[userresultsperpage] = 100;
			if (empty($this->request->get[page_number])) $this->request->get[page_number] = $_SESSION[userresultsperpage];
			if (!isset($this->request->get[page])) $this->request->get[page] = 1;
			$this->request->get[page_offset] = ($this->request->get[page]-1)*$this->request->get[page_number];

			if (($this->checkAccess)&&(!isset($_SESSION[access][$_SERVER[REDIRECT_URL]])))
			{
				//check access
				if ($object->config->use_table_access) $this->CheckPermissionsTables($url);
				//check column permissions
				if ($object->config->use_column_permissions) $this->CheckPermissionsColumns($url);
				//check row permissions
				if ($object->config->use_row_permissions) $this->CheckPermissionsRows($url);
				//check logging commentation
				if (($object->config->use_logging_commentation)&&($object->config->use_logging)&&(ereg('^(edit){1}[a-z_]*', $url[action])))
					$this->CheckColumnLoggingCommentation();			
			}
			
			//puts a 'permit' for this page into session
			$_SESSION[access][$_SERVER[REDIRECT_URL]] = true;
		}
		
	    /**
		 * Is loaded after any controller and performs common for all controllers actions
		 *
		 * @param array $url page url, devided into controller, action and parameters 
		 */			
		function AfterLoad($url)
		{
			//Logger::Debug("AfterLoad started");
			global $object;
			
			//displays informational table
			if ((ereg('^(add){1}[a-z_]*', $url[action]))||(ereg('^(edit){1}[a-z_]*', $url[action])))
			{
				$res = $this->controller_model->CheckRequiredFields();
				if ($res == true)
				{
					$this->helpers->htmlx->InformationTable(LANG_REQUIRED_FIELDS,'100%','attention.gif', 36,33);
				}
			}
			
			//if $use_logging in config.php is set to TRUE
			if (($object->config->use_logging) && ($this->name != 'main') && ($this->use_logging) && ($this->controller_model->database_config == 'db_config_default'))
			{
				//view/hide logs if the user has rights
				if (($_SESSION[table_accesses][t_system_logs][access_list]||(!$object->config->use_table_access))&&(!ereg('^(add){1}[a-z_]*', $url[action])))
				{
					echo "<br /><br /><br />";
					$this->helpers->htmlx->Button('show_logs', ucfirst(LANG_SHOW_HIDE_LOGS), "class='submit' onClick='GetLogs(\"/main/GetLogs/\")'");
					echo "<span id = 'logs'></span>";
					
					$_SESSION[url] = $url;
				}
			}
			//Logger::Debug("AfterLoad ended");
		}
		
	    /**
		 * Get logs for the current url. Used in AJAX functions
		 */			
		function GetLogs()
		{
			header('Content-Type: text/html; charset=windows-1251');
			echo "@";
			
			$this->DisplayLogs($_SESSION[url]);
			exit();
		}
		
	    /**
		 * Displays logs tables for the current url.
		 *
		 * @param array $url page url, devided into controller, action and parameters
		 */			
		function DisplayLogs($url)
		{
			global $object;
			
			//view insert logs for index files
			if (ereg('^(index){1}[a-z_]*', $url[action]))
			{
				//logs for the insert operation
				$parameters = array('num_rows');
				$logs = $this->GetModelObject('SystemLogs')->ListItemsPaged(array('table_name'=>$this->GetModelObject($url[controller])->table_name, 'row_id'=>0), 'sp_system_logs_list_paged',$parameters);
				$fields = array
				(
					'user_login'=>array
					(
						'title'=>LANG_USER,
						'url'=>'users',
						'id'=>'user_id'
					),
					
					'action_name'=>array
					(
						'title'=>LANG_ACTION,
					),
						
					'column_name'=>array
					(
						'title'=>LANG_COLUMN,
					),
					
					'value'=>array
					(
						'title'=>LANG_VALUE,
					),
					
					'datetime'=>array
					(
						'title'=>LANG_DATETIME,
					),
				);
				
				//logs for the delete operation
				$parameters = array('num_rows');
				$logs_delete = $this->GetModelObject('SystemLogs')->ListItemsPaged(array('table_name'=>$this->GetModelObject($url[controller])->table_name, 'action_name'=>'delete'), 'sp_system_logs_list_paged',$parameters);
				$fields_delete = array
				(
					'user_login'=>array
					(
						'title'=>LANG_USER,
						'url'=>'users',
						'id'=>'user_id'
					),
					
					'row_id'=>array
					(
						'title'=>LANG_RECORD_ID,
					),
					
					'action_name'=>array
					(
						'title'=>LANG_ACTION,
					),
					
					'datetime'=>array
					(
						'title'=>LANG_DATETIME,
						'url' => $url[controller],
						'id' => 'row_id'
					),
				);
				
			}

			//view update logs for edit/view files
			else if ((ereg('^(view){1}[a-z_]*', $url[action]))||(ereg('^(edit){1}[a-z_]*', $url[action])))
			{
				$parameters = array('num_rows');
				$logs = $this->GetModelObject('systemlogs')->ListItemsPaged(array('table_name'=>$this->GetModelObject($url[controller])->table_name, 'row_id'=>$url[parameters][0]), 'sp_system_logs_list_paged',$parameters);
				
				$fields = array
				(
					'user_login'=>array
					(
						'title'=>LANG_USER,
						'url'=>'users',
						'id'=>'user_id'
					),
					
					'action_name'=>array
					(
						'title'=>LANG_ACTION,
					),
						
					'column_name'=>array
					(
						'title'=>LANG_COLUMN,
					),
					
					'value_old'=>array
					(
						'title'=>LANG_OLD_VALUE,
					),
					
					'value'=>array
					(
						'title'=>LANG_VALUE,
					),
					
					'datetime'=>array
					(
						'title'=>LANG_DATETIME,
						'url' => $url[controller],
						'id' => 'row_id'
					),		
				);				
			}
			
			if ($object->config->use_logging_commentation)
			{
				$fields[comment] = array					
				(
					'title'=>LANG_COMMENT,
				);
				
				$fields_delete[comment] = array					
				(
					'title'=>LANG_COMMENT,
				);
			}
			
			//logs for the deleted records
			if (!empty($logs_delete))
			{
				echo "<table width='100%' id='logs_table'><tr><td>";
				echo "<hr style='margin-top: 5px;' />";
				$this->helpers->htmlx->MenuText1(LANG_LOGS.': '.LANG_LIST.' ('.LANG_DELETED.')', "list.gif");		
				$this->helpers->grids->GridLogs($logs_delete, $fields_delete);
				echo "</td></tr></table>";
			}
			
			//logs for the inserted and updated records
			if (!empty($logs))
			{
				echo "<table width='100%' id='logs_table'><tr><td>";
				$this->helpers->htmlx->MenuText1(LANG_LOGS.': '.LANG_LIST, "list.gif");		
				$this->helpers->grids->GridLogs($logs, $fields);
				echo "</td></tr></table>";
			}			
			
			//if no logs found
			else
			{
				echo "<table width='100%' id='logs_table'><tr><td>";
				echo LANG_NO_LOGS;
				echo "</td></tr></table>";
			}
		}
	
		/**
		 * Checks if the user is logged in
		 * 
		 * @param $action current action
		 * @return boolean
		 */
		function CheckAuthentication($action)
		{
			//for public pages
			if (in_array($action, $this->publicPages)) return true;

			//for customer pages
			if (in_array($action, $this->privatePages))
			{
				if (!empty($_SESSION['client']))
				{
					return true;
				}
				else
				{
//					$_SESSION['redirect_url'] = $_SERVER['REQUEST_URI'];
					header ("Location: /?login=1");
					exit();
				}
			}			
			
			//for admin pages
			if (empty($_SESSION['userid']) && ($action != 'login'))
			{
				$_SESSION['redirect_url'] = $_SERVER['REQUEST_URI'];
				header ("Location: /main/login");
				exit();
			}
		}		
		
	    /**
		 * Checks access to the page by the table name
		 *
		 * @param array $url page url, devided into controller, action and parameters 
		 */			
		function CheckPermissionsTables($url)
		{
			global $object;
			
    		//gets table access for the current user
			$access = $this->GetModelObject('systemAccess')->Execute(array('user_id'=>$_SESSION[userid], 'table_name'=>$this->controller_model->table_name), 'sp_system_access_get_by_user');			

			//by default we allow nothing
			$allow = 0;		

			//checks table access
			switch (true)
			{
				case (ereg('^(index){1}[a-z_]*', $url[action])): if (!empty($access[access_list])) $allow=1; break;
				case (ereg('^(add){1}[a-z_]*', $url[action])): if (!empty($access[add])) $allow=1; break;
				case (ereg('^(view){1}[a-z_]*', $url[action])): if (!empty($access[view])) $allow=1; break;
				case (ereg('^(edit){1}[a-z_]*', $url[action])): 
					if (!empty($access[edit])) $allow=1;
					else if (!empty($access[view]))
					{
						$redirect_url = str_replace('edit', 'view', $_SERVER[REDIRECT_URL]);
						header("Location: $redirect_url");
					}
					break;
				case (ereg('^(delete){1}[a-z_]*', $url[action])): if (!empty($access[delete])) $allow=1; break;
				default: $allow = 1; break;
			}
			
			//checks if we have delegated rights
			if (($allow==0)&&($object->config->use_delegations))
			{
				$normalized_url = $this->NormalizeURL('/'.$_SERVER[SERVER_NAME].$_SERVER[REDIRECT_URL]);

				$access_delegation = $this->GetModelObject('SystemAccess')->Execute(array('user_id'=>$_SESSION[userid], 'table_name'=>$this->controller_model->table_name, 'url'=>$normalized_url), 'sp_system_delegations_check_access');
				
				if (!$access_delegation[access_url])
				{
					switch (true)
					{
						case (ereg('^(index){1}[a-z_]*', $url[action])): if (!empty($access_delegation[access_list])) $allow=1; break;
						case (ereg('^(add){1}[a-z_]*', $url[action])): if (!empty($access_delegation[add])) $allow=1; break;
						case (ereg('^(view){1}[a-z_]*', $url[action])): if (!empty($access_delegation[view])) $allow=1; break;
						case (ereg('^(edit){1}[a-z_]*', $url[action])): if (!empty($access_delegation[edit])) $allow=1; break;
						case (ereg('^(delete){1}[a-z_]*', $url[action])): if (!empty($access_delegation[delete])) $allow=1; break;
					}
				}
				else $allow = 1;
			}
			
			//redirect to the referer page, if we have no rights for the current page
			if ($allow==0)
			{
				$this->DenyAccess();
			}
		}

	    /**
		 * Checks permissions for the given record
		 *
		 * @param array $url page url, devided into controller, action and parameters 
		 */	
		function CheckPermissionsColumns($url)
		{
			//gets column access for the current table and user
			$columns_access = $this->GetModelObject('systemPermissionsColumns')->ListItems(array('user_id'=>$_SESSION[userid], 'system_table_name'=>$this->controller_model->table_name), 'sp_system_permissions_columns_get_by_user');
			foreach ($columns_access as $column_access)
			{
				if(is_array($this->controller_model->db_structure))
				foreach ($this->controller_model->db_structure as $key=>$value)
				{
					if ($value[name]==$column_access[system_table_column_name]) $column_name = $key; 
				}
				
				if ($column_access[edit]) $this->general[columns][$column_name][edit] = 1;
				if ($column_access[view]) $this->general[columns][$column_name][view] = 1;				
			}			
		}
		
	    /**
		 * Checks permissions for the given record
		 *
		 * @param array $url page url, devided into controller, action and parameters 
		 */			
		function CheckPermissionsRows($url)
		{
			global $object; 

			//by default we allow everything
			$allow = 1;

			if (($url[action]=='view')||($url[action]=='edit')||($url[action]=='delete'))
			{
				$row_permissions_model = $this->GetModelObject('SystemPermissionsRows');
				$row_permissions = $row_permissions_model->Execute(array('system_table_name'=>$this->controller_model->table_name, 'row_id'=>$url[parameters][0], 'user_id'=>$_SESSION[userid]), 'sp_system_permissions_rows_for_user_check');
				
				//if we have parent/child permission check turned on in the config file
				if (($object->config->use_row_parent_child_permissions)&&(isset($url[parameters][0])))
				{
					$not_allow = $row_permissions_model->Execute(array('system_table_name'=>$this->controller_model->table_name, 'row_id'=>$url[parameters][0], 'user_id'=>$_SESSION[userid]), 'sp_system_permissions_rows_allow');
					if (!empty($not_allow[child])) $allow = 0;
					else $allow = 1;
				}
				else $allow = 1;
			}		
			
			//checks row permissions
			if (!empty($row_permissions))
			{
				switch(true)
				{
					case (ereg('^(view){1}[a-z_]*', $url[action])): if ($row_permissions[view]==='0') $allow=0; break;
					case (ereg('^(edit){1}[a-z_]*', $url[action])): if ($row_permissions[edit]==='0') $allow=0; break;
					case (ereg('^(delete){1}[a-z_]*', $url[action])): if ($row_permissions[delete]==='0') $allow=0; break;
				}
			}
			
			//checks if we have delegated rights for the given row
			if (($allow==0)&&($object->config->use_delegations))
			{
				$normalized_url = $this->NormalizeURL('/'.$_SERVER[SERVER_NAME].$_SERVER[REDIRECT_URL]);

				$row_permissions_delegation = $row_permissions_model->Execute(array('user_id'=>$_SESSION[userid], 'system_table_name'=>$this->controller_model->table_name, 'url'=>$normalized_url, 'row_id'=>$url[parameters][0]), 'sp_system_delegations_check_permissions_rows');

				//if we haven't got url delegation
				if (!$row_permissions_delegation[access_url])
				{
					if (empty($row_permissions_delegation)) $allow = 1;
					else
					{
						switch (true)
						{
							case (ereg('^(view){1}[a-z_]*', $url[action])): if (!empty($row_permissions_delegation[view])) $allow=1; break;
							case (ereg('^(edit){1}[a-z_]*', $url[action])): if (!empty($row_permissions_delegation[edit])) $allow=1; break;
							case (ereg('^(delete){1}[a-z_]*', $url[action])): if (!empty($row_permissions_delegation[delete])) $allow=1; break;
						}
					}
				}
				else $allow = 1;
			}
			
			//redirect to the referer page, if we have no rights for the current page
			if ($allow==0)
			{
				$this->DenyAccess();
			}
		}

	    /**
		 * Checks whether the columns' values change for the current table should be commented
		 *
		 * @param array $url page url, devided into controller, action and parameters 
		 */			
		function CheckColumnLoggingCommentation()
		{
			$column_logs = $this->GetModelObject('systemTablesColumnsLogs')->ListItems(array('system_table_id'=>$this->data[general][table_id]), 'sp_system_tables_columns_logs_list');

			foreach ($column_logs as $log)
			{				
				foreach ($this->controller_model->db_structure as $key=>$value)
				{
					if ($value[name]==$log[system_table_column_name]) $column_name = $key;
				}
				
				if (!$log[table_is_commented]) $this->general[log_comments][$column_name] = 0;
				else 
				{
					if ($log[is_commented]) $this->general[log_comments][$column_name] = 1;
					else $this->general[log_comments][$column_name] = 0;		
				}
			}			
		}

	    /**
		 * Redirects to the referer page, if we have no rights for the current page
		 */			
		function DenyAccess()
		{
			echo "<script langauge='javascript'>";
			echo "alert('".LANG_NO_ACCESS."');";
			echo "window.location.replace(document.referrer)";
			echo "</script>";					
			echo "<noscript>";
			echo LANG_NO_JS;
			echo "</noscript>";
			header("Location: $_SERVER[HTTP_REFERER]");
			exit();
		}
		
	    /**
		 * Loads appropriate view for the current controller
		 *
		 * @param array $parsed_url page url, devided into controller, action and parameters 
		 */			
		function LoadView($parsed_url)
		{
			$result = parent::LoadView($parsed_url);
			if ($result == false)
			{
				if ($parsed_url[controller] != 'main') $this->Redirect('pagenotexists');
				else return false;
			}
			else 
			{
				return $result;
			}
		}
		
	    /**
		 * Remembers show/hide filter decision for AJAX functions
		 *
		 * @param string $$controller controller name
		 * @param boolean $value indicates whether to expand filter or not
		 */			
		function ShowHideFilter($controller, $value)
		{	
			$_SESSION[$controller][show_filter] = $value;
		}
	
		/**
		 * Draws all the closed lotteries
		*/
		function DrawLotteries()
		{
			//bad lotteries
			$lotteries = $this->GetModelObject('lotteries')->ListItems('', 'sp_lotteries_list_to_close_without_draw');
			
			foreach ($lotteries as $key => $value)
			{
				$this->GetModelObject('clientsLotteries')->Execute(array('lottery_id' => $value['id']), 'sp_lotteries_close_without_draw');
			}
			
			//good lotteries
			$lotteries = $this->GetModelObject('lotteries')->ListItems('', 'sp_lotteries_list_to_draw');

			// for each full lottery
			foreach ($lotteries as $key => $value)
			{
				$lottery = $this->GetModelObject('clientsLotteries')->ListItems(array('lottery_id' => $value['id']), 'sp_clients_lotteries_list_for_lottery_draw');
				$seed = array();
				
				//for each participant filling seed array
				foreach ($lottery as $key2 => $client)
				{
					for ($i = 0; $i < $client['tickets_num']; ++$i)
					{
						array_push($seed, $client['client_id']);
					}
				}

				// drawing
				$winner = $seed[array_rand($seed)];
				
				//updating
				$this->controller_model->Execute(array('client_id' => $winner, 'id' => $value['id']), 'sp_lotteries_draw');

			}
		}
			
			
		
	    /**
		 * Puts the cut record id into the SESSION
		 *
		 * @param integer $id record id
		*/			
		function ClipboardCut($id)
		{
			$_SESSION[clipboard][id] = $id;
		}
		
	    /**
		 * Pastes the cut/copied record for the given parent_id
		 *
		 * @param integer $parent_id parent record id for which the record is pasted
		 */			
		function ClipboardPaste($parent_id, $id)
		{
			//if ($parent_id != $_SESSION[clipboard][id])
			if ($parent_id != $id)
			{
				//$this->GetModelObject('Main')->Update(array('parent_id'=>$parent_id, 'record_id'=>$_SESSION[clipboard][id], 'table_name'=>$this->controller_model->table_name), 'sp_update_parent');
				$this->GetModelObject('Main')->Update(array('parent_id'=>$parent_id, 'record_id'=>$id, 'table_name'=>$this->controller_model->table_name), 'sp_update_parent');
			}
			unset($_SESSION[clipboard][id]);
		}
		
		/**
		 * Remembers element's position in the SESSION
		 *
		 * @param string $element_id element's id or 'clear' if we want to clear $_SESSION[dragndrop]
  		 * @param integer $position_top top position
		 * @param integer $position_left left position
		*/			
		function DragNDrop($element_id, $position_top, $position_left)
		{
			if ($element_id == 'clear') unset($_SESSION[dragndrop]);
			else 
			{
				$theme = $_SESSION[usertheme];
				$_SESSION[dragndrop][$theme][$element_id] = "style = 'top: $position_top; left: $position_left'";
			}
		}
		
		/**
		 * Normalizes URL: adds default action and slashes, removes get parameters
		 *
		 * @param string $url url
		 * @return string normalized url
		 */			
		function NormalizeURL($url)
		{
			global $object;
			
			$pos = strpos($url, '?');	
			$pos1 = strpos($url, $_SERVER[SERVER_NAME])+strlen($_SERVER[SERVER_NAME]);	
			if ($pos) $returned_url = substr($url, $pos1, $pos - $pos1);
			else $returned_url = substr($url, $pos1);	
			$pos2 = strrpos ($returned_url,'/');
			$slash_numbers = substr_count($returned_url,'/');
			if($pos2==0) $returned_url = $returned_url.'/'.$object->config->defaultAction.'/';
			elseif ($slash_numbers==2&&strlen($returned_url)==$pos2+1) 
				$returned_url = $returned_url.$object->config->defaultAction.'/';
			elseif(strlen($returned_url)!=$pos2+1)
				$returned_url = $returned_url.'/';
			
			return $returned_url;
		}
		
	    /**
		 * Allows mass operations in all controllers (for grids)
		 */			
		function MassOperations()
		{
			if (!empty($this->request->post[delete]))
			{
				foreach ($this->request->post[chk] as $key=>$value)
				{			
					$this->GetModelObject($this->request->post[model_name])->Delete($key);	
				}
				header("Location: {$_SERVER[HTTP_REFERER]}");
			}			
		}
		
		/**
		 * Displays theme sample
		 *
		 * @param string $img theme name
		 */
		function EditThemeImage($img)
		{
			echo "@<img src = /./".THEMES.SEPARATOR.$img.SEPARATOR.'screenshot.gif'.">";
			exit();
		}
		
		/**
		 * Uploads image for the parent object
		 *
		 * @param string $name name of the file
		 * @param string $parent_id parent object id
		 * @param string $model_name
		 * @param string $parent_id_name
		 */
		function UploadFile($name, $base_folder, $parameters = array(), $db_parameters = array())
		{
			if (empty($_FILES[$name]['name'])) return;
			
			$max_size = (!empty($parameters['max_size'])) ? $parameters['max_size'] : 3000000; //the max. size for uploading (in bytes)
			define("MAX_SIZE", $max_size);
			
			$foto_upload = new Foto_upload;
			
			//default parameters
			$foto_upload->x_max_size = (isset($parameters['x_max_size'])) ? $parameters['x_max_size'] : 800;
			$foto_upload->y_max_size = (isset($parameters['y_max_size'])) ? $parameters['y_max_size'] : 800;
			
			//removed because of min thumb size workaround.
			$foto_upload->x_max_thumb_size = (isset($parameters['x_max_thumb_size'])) ? $parameters['x_max_thumb_size'] : 200;
			$foto_upload->y_max_thumb_size = (isset($parameters['y_max_thumb_size'])) ? $parameters['y_max_thumb_size'] : 300;

			//Upload path
			define('UPLOAD','/app/upload/'.$base_folder);
			
			//configuration
			$foto_upload->rename_file = false;
			$foto_upload->upload_dir = $_SERVER['DOCUMENT_ROOT'].'/app/temp/'.SEPARATOR; // files is the folder for the uploaded files (you have to create these folder)
			$foto_upload->foto_folder = $_SERVER['DOCUMENT_ROOT'].UPLOAD.SEPARATOR;
			$foto_upload->thumb_folder = $_SERVER['DOCUMENT_ROOT'].UPLOAD.SEPARATOR.'thumbs/';
			$foto_upload->extensions = (empty($parameters['extensions'])) ? array(".jpg", ".gif", ".png", ".JPG", ".GIF", ".PNG") : $parameters['extensions']; // specify the allowed extension(s) here
			$foto_upload->language = (empty($parameters['language'])) ? "en" : $parameters['language'];
			$foto_upload->the_temp_file = $_FILES["$name"]['tmp_name'];
			$foto_upload->the_file = $_FILES["$name"]['name'];
			$foto_upload->http_error = $_FILES["$name"]['error'];
			$foto_upload->replace = (isset($_POST['replace'])) ? $_POST['replace'] : "y"; // because only a checked checkboxes is true
			$foto_upload->do_filename_check = "n"; 
			
			//if uploaded successfully
			if ($foto_upload->upload()) 
			{
				//image process
				$foto_upload->process_image(false, true, true, 80);
				
				//db call if necessary
				if (!empty($db_parameters))
				{
					//db parameters string
					$db_parameters_string = '';
					foreach ($db_parameters['parameters'] as $key => $value)
					{
						$db_parameters_string .= "'".$key."' => '".$value."',";
					}
					
					if (isset($db_parameters['stored_procedure'])) $stored_procedure_string = ", ".$db_parameters['stored_procedure'];
					else $stored_procedure_string = '';
					
					//db call string 
					$db_call = '
						$this->GetModelObject("'.$db_parameters[model].'")->Update(array
							(
								'.$db_parameters_string.'
								\''.$db_parameters["image_db_name"].'\' => \''.$foto_upload->file_copy.'\'
							)'.$stored_procedure_string.');
					';
					
					//updates DB
					eval($db_call);
				}
			}
			
			//result
			$return_message = $foto_upload->show_error_string();
			
			return $return_message;
		}		
		
		/**
		 * Deletes the photo from the database and file system
		 * 
		 * @param $id
		 * @param $name
		 */
		function DeletePhoto($id, $name)
		{
			$this->controller_model->Delete($id);
			
			$folder = $_GET['folder'];

			unlink($_SERVER[DOCUMENT_ROOT]."/app/upload/$folder/$name");
			unlink($_SERVER[DOCUMENT_ROOT]."/app/upload/$folder/thumbs/$name");
			
			exit();
		}		
		
		/**
		 * Exports array to a spreadsheet file
		 *
		 * @param array $data data array
		 * @param string $path_to_file file name with the path
		 */
		function ExportToSpreadsheet(array $data, $path_to_file)
		{
			$spreadsheet = new SpreadsheetExport();
			$spreadsheet->CreateFileFromArray($data, $path_to_file);			
		}
		
		/**
		 * Tries to translate constant
		 *
		 * @param string $lang_const language constant
		 * @param string $alternative alternative if translation not found
		 * @return string translation
		*/	
		function Translate($lang_const, $alternative)
		{
			$result = $lang_const;
			eval("\$lang_const = $lang_const;");
			
			if ($result == $lang_const)
			{
				$result = $alternative;
			}
			else
			{
				$result = $lang_const;			
			}
			
			return $result;
		}		

		/**
		 * Includes HTML file from the {language}/html folder
		 *
		 * @param string $filename name of the file without extention
		 */
		function IncludeHTMLPage($filename)
		{
			include_once(LANGUAGES.SEPARATOR.$_SESSION['lang'].SEPARATOR."html/$filename.html");
		}		
		
		/**
		 * Gets data from the pool
		 *
		 * @param string $name
		 */
		function GetListFromPool($name)
		{
			if (!isset($_SESSION['pool'][$name]))
			{
				$result = $this->GetModelObject($name)->ListItems();
				$_SESSION['pool'][$name] = $result;
			}
			else
			{
				
			}
			return $_SESSION['pool'][$name];
		}
		
		/**
		 * Gets data from the we service pool
		 *
		 * @param string $name
		 */
		function GetReferenceData($name = '')
		{
//			$_SESSION['pool']['reference'] = array();
			if (empty($_SESSION['pool']['reference']))
			{
				//reference data
				$webService = new WebService();
				$referenceData = $webService->XMLCall("http://mturk.nebulent.com/mturk-blazeds/ws/EdieWorkersWebService?wsdl"
					, "getWorkersReferenceData"
					, array('getWorkersReferenceData' => array('getAll' => 'true'))
					, array('XML_object_by_attributes' => true)
					, array('SOAPAction' => 'getWorkersReferenceData')		
					, array('mes' => 'http://mturk.nebulent.com/service/messages'));
//				Debugger::VarDump($referenceData);
					
				//interests parsing	
				foreach ($referenceData['interests'] as $key => $interest)
				{
					$result['interests'][$key]['uuid'] = $interest['!uuid'];
					$result['interests'][$key]['name'] = $interest['!name'];
				}
				
				//languages parsing	
				foreach ($referenceData['languages'] as $ki => $language)
				{
					$result['languages'][$ki]['uuid'] = $language['!uuid'];
					$result['languages'][$ki]['name'] = $language['!name'];
				}
				
				//locations parsing	
				foreach ($referenceData['locations'] as $k => $location)
				{
					$result['locations'][$k]['uuid'] = $location['!uuid'];
					$result['locations'][$k]['name'] = $location['!stateProvince'].' ('.$location['!country'].')';
				}

				$_SESSION['pool']['reference'] = $result;
			}
			else
			{
				
			}
			return $_SESSION['pool']['reference'];
		}
				
		
		/* SITE FUNCTIONS */
		
		/**
		 * Gets the logged client
		 *
		 */
		protected function GetCurrentClient()
		{
			return HTTPContext::$session['client'];
		}		

		/**
		 * Sets the logged client
		 *
		 */
		protected function SetCurrentClient($client)
		{
			foreach ($client as $key => $value)
			{
				if (isset(HTTPContext::$session['client'][$key]))
				{
					HTTPContext::$session['client'][$key] = $value;
					$_SESSION['client'][$key] = $value;
				}
			}
		}		
		
		
		/**
		 * Counts followers number based on given client id
		 *
		 * @param int $clientId
		 * @return int number of referrals
		 */
		protected function CountFollowers($clientId)
		{
			$followers = $this->GetModelObject('Clients')->Execute(array('id' => $clientId), 'sp_clients_count_followers');
			
			return $followers['id'];
		}			
		
		/**
		 * Counts refferals number based on given client id
		 *
		 * @param array $clients clients
		 * @param int $clientId
		 * @return int number of referrals
		 */
		protected function CountReferrals($clients, $clientId)
		{
			foreach ($clients as $client)
			{
				if ($client['parent_id'] == $clientId)
				{
					$count++;
					$count += $this->CountReferrals($clients, $client['id']);
				}
			}
			
			return $count;
		}		
		
		/**
		 * Gets date range text
		 *
		 * @param array $item
		 * @return string
		 */
		function GetDateRangeText($item)
		{
			$startMonth = Arrays::$months[intval(date('m', strtotime($item['start_date'])))]['name'];
			$endMonth = Arrays::$months[intval(date('m', strtotime($item['end_date'])))]['name'];

			return ($startMonth == $endMonth) ? date('j', strtotime($item['start_date'])).' - '.date('j', strtotime($item['end_date'])).' '.$startMonth : date('j', strtotime($item['start_date'])).' '.$startMonth.' - '.date('j', strtotime($item['end_date'])).' '.$endMonth;
		}
		
		/**
		 * Sends Gmail message
		 *
		 * @param array $recipients
		 * @param string $subject
		 * @param string $text
		 * @return boolean
		 */
		function SendMail(array $recipients, $subject, $text)
		{
	        //mail sending
	    	$message = array
	    	(
	    		 'fromName' => 'Markedd',
	    		 'subject' => '[Markedd] '.$subject,
	    		 'text' => $text,
	    		 'recipients' => $recipients
	    	);	

	    	return Gmail::Send($message);
		}
		
		/**
		 * Checks if the user is active
		 *
		 * @return boolean
		 */
		function CheckActivation()
		{
			$guid_1 = trim($_SESSION['customer']['guid_1']);
			$guid_2 = trim($_SESSION['customer']['guid_2']);

			return (empty($guid_1) && empty($guid_2) && !empty($_SESSION['customer']['id']));
		}
		
		
		/* AJAX FUNCTIONS */
		
		/**
		 * Toggles the left column
		 */
		function ToggleLeftColumn()
		{
		    $_SESSION['show']['left_column'] = 
		        (($_SESSION['show']['left_column'] == true) || (!isset($_SESSION['show']['left_column']))) ? false : true;
		}
		
		/**
		 * Toggles the header
		 */
		function ToggleHeader()
		{
		    $_SESSION['show']['header'] = 
		        (($_SESSION['show']['header'] == true) || (!isset($_SESSION['show']['header']))) ? false : true;
		}
		
		
		/* STANDARD ACTIONS */
		
		/**
		 * Lists all items
		 */
		function Index()
		{
			$parameters = array('num_rows');
			$this->data[$this->name] = $this->controller_model->ListItemsPaged($this->request->get, '', $parameters);
			$this->data[num_rows] = $parameters[num_rows];
		}
		
		/**
		 * Edits the item
		 */
		function Edit($id)
		{
			$this->data[$this->name] = $this->controller_model->Get($id);			
			if (!empty($this->request->post))
			{
				
				if ($this->controller_model->Update($this->request->post))
				{
					$this->Redirect($this->name);
				}
				else
				{
					$this->data[$this->name] = $this->request->post;				
				}
			}
			else
			{

			}	
		}
		
		/**
		 * Adds an item
		 */
		function Add()
		{
			if (!empty($this->request->post))
			{
				if ($this->controller_model->Update($this->request->post))
				{
					$this->Redirect($this->name);
				}
				else
				{
					$this->data[$this->name] = $this->request->post;				
				}
			}
			else
			{

			}	
		}
		
		/**
		 * Displays the item
		 */
		function View($id)
		{
			$this->data[$this->name] = $this->controller_model->Get($id);
		}
		
		/**
		 * Deletes the item
		 */
		function Delete($id, $confirm = 0)
		{ 
			if ($confirm)
			{
				$this->controller_model->Delete($id);
				$this->Redirect($this->name);
			}
			else
			{
				$this->layout = "empty";
				$this->data[$this->name]['id'] = $id;
			}
		}		
	}		
?>